#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 20

typedef int (*List_traverse_cb)(int *);

typedef struct
{
    int data[MAXSIZE];
    int length;
} SqList;

SqList *InitList();
void DestroyList(SqList *L);
int ListEmpty(SqList *L);
int ListLength(SqList *L);
int GetElem(SqList *L, int i, int *e);
int LocateElem(SqList *L, int e);
int ListInsert(SqList *L, int i, int e);
int ListDelete(SqList *L, int i, int *e);
int ListTraverse(SqList *L, List_traverse_cb traverse_cb);

static int cell_method(int *e)
{
    printf("cell_method: %d\n", *e);
    return 0;
}

int main()
{
    SqList *L = NULL;
    L = InitList();

    int i1 = 10;
    int i2 = 20;
    int i3 = 30;

    ListInsert(L, 1, i1);
    ListInsert(L, 2, i2);
    ListInsert(L, 1, i3);

    int e1;
    int e2;
    int e3;
    GetElem(L, 1, &e1);
    GetElem(L, 2, &e2);
    GetElem(L, 3, &e3);
    printf("GetElem: element at index 1 is %d\n", e1);
    printf("GetElem: element at index 2 is %d\n", e2);
    printf("GetElem: element at index 3 is %d\n", e3);
    
    

    return 0;
}

SqList *InitList()
{
    SqList *L = (SqList *)malloc(sizeof(SqList));
    if (!L)
    {
        printf("InitList: malloc failed\n");
        return NULL;
    }
    L->length = 0;
    return L;
}

int ListEmpty(SqList *L)
{
    if (L->length == 0)
        return 0;
    else
        return 1;
}

int ListInsert(SqList *L, int i, int e)
{
    if (i < 1 || i > L->length + 1)
    {
        printf("ListInsert: i is out of range\n");
        return -1;
    }
    if (L->length >= MAXSIZE)
    {
        printf("ListInsert: list is full\n");
        return -1;
    }
    if (ListEmpty(L) == 0)
    {
        L->data[0] = e;
        L->length++;
        return 0;
    }
    if (i <= L->length)
    {
        for (int j = L->length - 1; j >= i - 1; j--)
        {
            L->data[j + 1] = L->data[j];
        }
    }
    L->data[i - 1] = e;
    L->length++;
    return 0;
}

int GetElem(SqList *L, int i, int *e)
{
    int status = ListEmpty(L);
    if (status == 0)
    {
        printf("GetElem: list is empty\n");
        return -1;
    }

    if (i < 1 || i > L->length)
    {
        printf("GetElem: i is out of range\n");
        return -1;
    }

    *e = L->data[i - 1];

    return 0;
}